/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_int_pend.c
 * @brief    中断挂起服务 - 执行函数（仅在PendSV中调用并执行）
 * @author   迟凯峰
 * @version  V1.0.0
 * @date     2023.10.20
 ******************************************************************************/

#include "os_link.h"

/* 恢复任务 */
static void _resume_task_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_task_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status & OS_STATUS_SUSPENDED){
		node->status &= (~OS_STATUS_SUSPENDED & 0xFF);
		if(!s_sign_scheduling){
			if(node->status <= OS_STATUS_FLOATING && node->pri > s_task_current->pri){
				s_sign_scheduling = true;
			}
		}
	}
}

/* 挂起任务 */
static void _suspend_task_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_task_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status < OS_STATUS_SUSPENDED){
		node->status |= OS_STATUS_SUSPENDED;
		if(!s_sign_scheduling){
			if(node == s_task_current){
				s_sign_scheduling = true;
			}
		}
	}
}

/* 删除任务 */
static void _delete_task_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_task_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status < OS_STATUS_DELETED){
		node->status = OS_STATUS_DELETED;
		if(!s_sign_scheduling){
			if(node == s_task_current){
				s_sign_scheduling = true;
			}
		}
	}
}

/* 设置任务优先级 */
static void _set_taskpri_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_taskpri_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status < OS_STATUS_STOPPED){
		s_u8_t pri = ((sp_taskpri_tsp)sv)->pri;
		if(node->pri == pri) return;
		node->pri = pri;
		sSetTaskPri(node);
		if(!s_sign_scheduling){
			if(pri > s_task_current->pri && node->status <= OS_STATUS_FLOATING){
				s_sign_scheduling = true;
			}
		}
	}
}

/* 设置阻塞（时间）*/
static void _set_block_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_blocktime_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status == OS_STATUS_BLOCKED || node->status == OS_STATUS_FLOATING){
		s_delay_loader[node->tid] = ((sp_blocktime_tsp)sv)->tick;
		if(!((sp_blocktime_tsp)sv)->tick){
			node->status = OS_STATUS_READY;
			if(!s_sign_scheduling){
				if(node->pri > s_task_current->pri){
					s_sign_scheduling = true;
				}
			}
		}
	}
}

/* 清除阻塞（状态）*/
static void _clear_block_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp node = ((sp_task_tsp)sv)->node;
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL) return;
	#endif
	if(node->status == OS_STATUS_BLOCKED || node->status == OS_STATUS_FLOATING){
		s_delay_loader[node->tid] = 0;
		node->status = OS_STATUS_READY;
		if(!s_sign_scheduling){
			if(node->pri > s_task_current->pri){
				s_sign_scheduling = true;
			}
		}
	}
}

/* 定时中断 */
#if OS_TIMINTTOTAL
static void _timint_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	  s_timint_loader[((sp_timint_tsp)sv)->tmid]
	= s_timint_reload[((sp_timint_tsp)sv)->tmid]
	= ((sp_timint_tsp)sv)->tick;
}
#else
#define _timint_ (s_voidvptr_tfp)NULL
#endif

/* 定时查询 */
#if OS_TIMQRYTOTAL
static void _timqry_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	  s_timqry_loader[((sp_timqry_tsp)sv)->tmid]
	= s_timqry_reload[((sp_timqry_tsp)sv)->tmid]
	= ((sp_timqry_tsp)sv)->tick;
}
#else
#define _timqry_ (s_voidvptr_tfp)NULL
#endif

/* 释放/上锁二值信号量 */
#if SYSCFG_BINARY == __ENABLED__
static void _binary_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	*((sp_binary_tsp)sv)->bin = ((sp_binary_tsp)sv)->value;
}
#else
#define _binary_ (s_voidvptr_tfp)NULL
#endif

/* 释放计数信号量 */
#if SYSCFG_SEMAPHORE == __ENABLED__
static void _give_sem_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	if(((sp_sem_tsp)sv)->sem->counter < ((sp_sem_tsp)sv)->sem->maximum){
		((sp_sem_tsp)sv)->sem->counter++;
	}
}
#else
#define _give_sem_ (s_voidvptr_tfp)NULL
#endif

/* 全局变量写访问 */
static void _gvar_write_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	si_gvar_tsp accessor = ((sp_gvar_tsp)sv)->accessor;
	sWrite_GVarAccessor((s_gvar_tsp)accessor);
	accessor->size
	? s_memcpy(accessor->gv, accessor->lv, accessor->size)
	: s_strcpy((char *)accessor->gv, (char *)accessor->lv);
	sWrite_GVarAccessor(NULL);
}

/* 全局变量自运算 */
static void _gvar_selfope_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	si_gvar_tsp accessor = ((sp_selfope_tsp)sv)->accessor;
	s_memcpy(accessor->lv, accessor->gv, accessor->size);
	sWrite_GVarAccessor((s_gvar_tsp)accessor);
	(*((sp_selfope_tsp)sv)->fp)();
	sWrite_GVarAccessor(NULL);
}

/* 发送飞信 */
#if SYSCFG_FETION == __ENABLED__
static void _send_fetion_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	*((sp_fetion_tsp)sv)->tbox = ((sp_fetion_tsp)sv)->fetion;
}
#else
#define _send_fetion_ (s_voidvptr_tfp)NULL
#endif

/* 发送邮件 */
#if SYSCFG_MAILBOX == __ENABLED__
static void _send_mail_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	si_mbox_tsp accessor = ((sp_mbox_tsp)sv)->accessor;
	#if SYSCFG_MAILBOX_ACCESSMECHANISM == 1
	accessor->lf = true;
	#endif
	sWrite_MBoxAccessor((s_mbox_tsp)accessor);
	s_memcpy(accessor->gm, accessor->lm, accessor->size);
	sWrite_MBoxAccessor(NULL);
	#if SYSCFG_MAILBOX_ACCESSMECHANISM == 0
	*accessor->gf = true;
	#elif SYSCFG_MAILBOX_ACCESSMECHANISM == 1
	*accessor->gf = accessor->lf;
	#endif
}
#else
#define _send_mail_ (s_voidvptr_tfp)NULL
#endif

/* 发送消息 */
#if SYSCFG_MSGQUEUE == __ENABLED__
static void _send_msg_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	s_msgqueue_tsp queue = ((sp_msg_tsp)sv)->queue;
	queue->mutex = false;
	if(queue->counter == queue->len){
		queue->mutex = true;
		#if SYSCFG_DEBUGGING == __ENABLED__
		s_alarm.overflow_msgqueue = true;
		#endif
		return;
	}
	if(queue->type == __DYNAMIC__){
		s_msgnode_tsp node = NULL;
		node = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
		if(node == NULL){
			queue->mutex = true;
			#if SYSCFG_DEBUGGING == __ENABLED__
			s_fault.mallocfailed_msgnode = true;
			#endif
			return;
		}
		sSendMsg_Dynamic(((sp_msg_tsp)sv)->msg);
	}
	else{
		sSendMsg_Static(((sp_msg_tsp)sv)->msg);
	}
	queue->mutex = true;
}
#else
#define _send_msg_ (s_voidvptr_tfp)NULL
#endif

/* 写标志组 */
#if SYSCFG_FLAGGROUP == __ENABLED__
static void _group_(void _OBJ_MEM_ *sv) MCUCFG_C51USING
{
	switch(((sp_group_tsp)sv)->size){
	case +1: *(s_u8_t  *)((sp_group_tsp)sv)->group |= ((sp_group_tsp)sv)->value; break;
	case +2: *(s_u16_t *)((sp_group_tsp)sv)->group |= ((sp_group_tsp)sv)->value; break;
	case +4: *(s_u32_t *)((sp_group_tsp)sv)->group |= ((sp_group_tsp)sv)->value; break;
	case -1: *(s_u8_t  *)((sp_group_tsp)sv)->group &=~((sp_group_tsp)sv)->value; break;
	case -2: *(s_u16_t *)((sp_group_tsp)sv)->group &=~((sp_group_tsp)sv)->value; break;
	case -4: *(s_u32_t *)((sp_group_tsp)sv)->group &=~((sp_group_tsp)sv)->value; break;
	}
}
#else
#define _group_ (s_voidvptr_tfp)NULL
#endif

typedef void (_CODE_MEM_ *s_voidvptr_tfp)(void _OBJ_MEM_ *);
void (_CODE_MEM_ * const _CONST_MEM_ sPendSV_Handler[OS_SVID_END])(void _OBJ_MEM_ *) =
{
	_resume_task_,
	_suspend_task_,
	_delete_task_,
	_set_taskpri_,
	_set_block_,
	_clear_block_,
	_timint_,
	_timqry_,
	_binary_,
	_give_sem_,
	_gvar_write_,
	_gvar_selfope_,
	_send_fetion_,
	_send_mail_,
	_send_msg_,
	_group_
};
